﻿#region Librerias

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing.Imaging;
using iTextSharp.text.pdf;
using System.Windows.Media.Imaging;
using ESF.General;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf.parser;

#endregion


namespace ESF.FileProcessing
{
	public static class PDFHelper
	{
		public static int GetItemCount(string pFileName)
		{
			PdfReader pdfR = null;
			

			if (Path.GetExtension(pFileName).ToUpper() == ".PDF")
			{
				try
				{
					pdfR = new PdfReader(pFileName);
					return pdfR.NumberOfPages;
				}
				finally 
				{
					if (pdfR != null)
					{
						pdfR.Close ();
					}
				}	
			}

			return 0;
		}


		// NOTE:  This will only get the first image it finds per page.
		public static void ExtractImagesFromPDF(string sourcePdf, string outputPath)
		{
			//ImageFormat imageFormat;

			PdfReader pdf = new PdfReader(sourcePdf);

			RandomAccessFileOrArray raf = new iTextSharp.text.pdf.RandomAccessFileOrArray(sourcePdf);

			try
			{
				for (int pageNumber = 1; pageNumber <= pdf.NumberOfPages; pageNumber++)
				{
					PdfDictionary pg = pdf.GetPageN(pageNumber);

					// recursively search pages, forms and groups for images.
					PdfObject obj = FindFirstImageInPDFDictionary(pg);

					if (obj != null)
					{
						FileHelper.EnsureFolder (outputPath);

						string path = Path.Combine(outputPath, String.Format(@"{0}.jpg", pageNumber));

						PdfDictionary tg = (PdfDictionary)PdfReader.GetPdfObject(obj);
						string width = tg.Get(PdfName.WIDTH).ToString();
						string height = tg.Get(PdfName.HEIGHT).ToString();
						ImageRenderInfo imgRI = ImageRenderInfo.CreateForXObject(new Matrix(float.Parse(width), float.Parse(height)),
							(PRIndirectReference)obj, tg);
						
						PdfImageObject image = imgRI.GetImage();

						File.WriteAllBytes (path, image.GetImageAsBytes ());

						/*using (MemoryStream ms = new MemoryStream (image.GetImageAsBytes ()))
						{
							dotnetImg.Save(ms, ImageFormat.Tiff);
							System.Drawing.Bitmap d = new System.Drawing.Bitmap(dotnetImg);
							d.Save(imgPath);
						}*/
						
						/*int XrefIndex = Convert.ToInt32(((PRIndirectReference)obj).Number.ToString(System.Globalization.CultureInfo.InvariantCulture));
						PdfObject pdfObj = pdf.GetPdfObject(XrefIndex);
						PdfStream pdfStrem = (PdfStream)pdfObj;
						byte[] bytes = PdfReader.GetStreamBytesRaw((PRStream)pdfStrem);

						if ((bytes != null))
						{
							string path = Path.Combine(outputPath, String.Format(@"{0}.jpg", pageNumber));

							imageFormat = ImageHelper.GetImageFormat(bytes);

							using (System.IO.MemoryStream memStream = new System.IO.MemoryStream(bytes))
							{
								// puede ser un tiff
								if (imageFormat == null)
								{File.WriteAllBytes ("c:\\aja.jpg", bytes);
									TiffBitmapDecoder decoder = new TiffBitmapDecoder(memStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);

									BmpBitmapEncoder encoder = new BmpBitmapEncoder();

									encoder.Frames.Add(decoder.Frames[0]);

									using (FileStream file = new FileStream(path, FileMode.Create))
									{
										encoder.Save(file);
									}
								}
								else
								{
									memStream.Position = 0;

									System.Drawing.Image img = System.Drawing.Image.FromStream(memStream);

									ESF.General.FileHelper.EnsureFolder(outputPath);

									System.Drawing.Imaging.EncoderParameters parms = new System.Drawing.Imaging.EncoderParameters(1);
									parms.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Compression, 0);
									System.Drawing.Imaging.ImageCodecInfo jpegEncoder = ImageHelper.GetEncoder(imageFormat);
									img.Save(path, jpegEncoder, parms);
								}
							}
						}*/
					}
				}
			}
			catch
			{
				throw;
			}
			finally
			{
				pdf.Close();
				raf.Close();
			}
		}


		private static PdfObject FindFirstImageInPDFDictionary(PdfDictionary pg)
		{
			List<PdfObject> imageList;


			imageList = FindImagesInPDFDictionary (pg);

			if (DataHelper.IsEmpty (imageList))
			{
				return null;
			}

			return imageList.First ();
		}


		private static List<PdfObject> FindImagesInPDFDictionary(PdfDictionary pg)
		{
			List<PdfObject> imageList = new List<PdfObject> ();


			FindImagesInPDFDictionary (pg, ref imageList);

			return imageList;
		}


		private static void FindImagesInPDFDictionary(PdfDictionary pg, ref List<PdfObject> pImageList)
		{
			PdfDictionary res = (PdfDictionary)PdfReader.GetPdfObject(pg.Get(PdfName.RESOURCES));

			PdfDictionary xobj = (PdfDictionary)PdfReader.GetPdfObject(res.Get(PdfName.XOBJECT));

			PdfObject obj;

			if (xobj != null)
			{
				foreach (PdfName name in xobj.Keys)
				{
					obj = xobj.Get(name);

					if (obj.IsIndirect())
					{
						PdfDictionary tg = (PdfDictionary)PdfReader.GetPdfObject(obj);

						PdfName type = (PdfName)PdfReader.GetPdfObject(tg.Get(PdfName.SUBTYPE));
					}
				}

				foreach (PdfName name in xobj.Keys)
				{
					obj = xobj.Get(name);

					if (obj.IsIndirect())
					{
						PdfDictionary tg = (PdfDictionary)PdfReader.GetPdfObject(obj);

						PdfName type = (PdfName)PdfReader.GetPdfObject(tg.Get(PdfName.SUBTYPE));

						//image at the root of the pdf
						if (PdfName.IMAGE.Equals(type))
						{
							pImageList.Add (obj);
						}// image inside a form
						else if (PdfName.FORM.Equals(type))
						{
							FindImagesInPDFDictionary(tg, ref pImageList);
						} //image inside a group
						else if (PdfName.GROUP.Equals(type))
						{
							FindImagesInPDFDictionary(tg, ref pImageList);
						}
					}
				}
			}
		}
	}
}
